import { Injectable, Logger } from "@nestjs/common";
import { CasinoDiceRoundService } from "./casino-dice-round.service";
import { CasinoChibiRoundService } from "./casino-chibi-round.service";
import { GameType } from "../entities/index";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import {
  CasinoDiceBet,
  BetType,
  CurrencyType,
  BetStatus,
} from "../entities/casino-dice-bet.entity";
import { getFrontendBetType } from "../enums/bet-type-mapping.enum";

// 兼容原有的接口类型
export interface UnifiedRoundData {
  id: number;
  gameType: GameType;
  roundNumber: number;
  startTime: Date;
  endTime: Date;
  status: number;
  resultData: any;
  totalGold: number;
  totalSilver: number;
  created_at: Date;
  updated_at: Date;

  // 兼容方法
  getDiceResult(): any;
  getChibiResult(): any;
  getRPSResult(): any;
}

@Injectable()
export class CasinoUnifiedRoundService {
  private readonly logger = new Logger(CasinoUnifiedRoundService.name);

  constructor(
    private readonly diceRoundService: CasinoDiceRoundService,
    private readonly chibiRoundService: CasinoChibiRoundService,
    @InjectRepository(CasinoDiceBet)
    private readonly diceBetRepository: Repository<CasinoDiceBet>
  ) { }

  /**
   * 获取当前活跃期数（分表逻辑）
   */
  async getCurrentRound(gameType: GameType): Promise<UnifiedRoundData | null> {
    try {
      let currentRound: any = null;

      switch (gameType) {
        case GameType.DICE:
          currentRound = await this.diceRoundService.getCurrentRound();
          break;
        case GameType.CHIBI:
          currentRound = await this.chibiRoundService.getCurrentRound();
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return null;
      }

      return currentRound
        ? this.convertRoundToUnified(currentRound, gameType)
        : null;
    } catch (error) {
      this.logger.error(
        `获取当前期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取指定期数（分表逻辑）
   */
  async getRoundByNumber(
    gameType: GameType,
    roundNumber: number
  ): Promise<UnifiedRoundData | null> {
    try {
      let round: any = null;

      switch (gameType) {
        case GameType.DICE:
          round = await this.diceRoundService.getRoundById(roundNumber);
          break;
        case GameType.CHIBI:
          round = await this.chibiRoundService.getRoundById(roundNumber);
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return null;
      }

      return round ? this.convertRoundToUnified(round, gameType) : null;
    } catch (error) {
      this.logger.error(
        `获取指定期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取最新已结算期数
   */
  async getLatestSettledRound(
    gameType: GameType
  ): Promise<UnifiedRoundData | null> {
    try {
      let latestRound: any = null;
      switch (gameType) {
        case GameType.DICE:
          latestRound = await this.diceRoundService.getLatestSettledRound();
          break;
        case GameType.CHIBI:
          latestRound = await this.chibiRoundService.getLatestSettledRound();
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return null;
      }
      return latestRound
        ? this.convertRoundToUnified(latestRound, gameType)
        : null;
    } catch (error) {
      this.logger.error(
        `获取最新已结算期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取最新期数（分表逻辑）
   */
  async getLastRound(gameType: GameType): Promise<UnifiedRoundData | null> {
    try {
      let lastRound: any = null;

      switch (gameType) {
        case GameType.DICE:
          lastRound = await this.diceRoundService.getLastRound();
          break;
        case GameType.CHIBI:
          lastRound = await this.chibiRoundService.getLastRound();
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return null;
      }

      return lastRound ? this.convertRoundToUnified(lastRound, gameType) : null;
    } catch (error) {
      this.logger.error(
        `获取最新期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 创建新期数（分表逻辑）
   */
  async createNewRound(
    gameType: GameType,
    startTime: Date,
    endTime: Date
  ): Promise<UnifiedRoundData> {
    try {
      let newRound: any = null;

      switch (gameType) {
        case GameType.DICE:
          newRound = await this.diceRoundService.createNewRound(
            startTime,
            endTime
          );
          break;
        case GameType.CHIBI:
          newRound = await this.chibiRoundService.createNewRound(
            startTime,
            endTime
          );
          break;
        default:
          throw new Error(`不支持的游戏类型: ${gameType}`);
      }

      return this.convertRoundToUnified(newRound, gameType);
    } catch (error) {
      this.logger.error(
        `创建新期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 关闭期数（分表逻辑）
   */
  async closeRound(roundId: number, gameType: GameType): Promise<void> {
    try {
      switch (gameType) {
        case GameType.DICE:
          await this.diceRoundService.closeRound(roundId);
          break;
        case GameType.CHIBI:
          await this.chibiRoundService.closeRound(roundId);
          break;
        default:
          throw new Error(`不支持的游戏类型: ${gameType}`);
      }
    } catch (error) {
      this.logger.error(
        `关闭期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 结算期数（分表逻辑）
   */
  async settleRound(roundId: number, gameType: GameType): Promise<void> {
    try {
      switch (gameType) {
        case GameType.DICE:
          await this.diceRoundService.settleRound(roundId);
          break;
        case GameType.CHIBI:
          await this.chibiRoundService.settleRound(roundId);
          break;
        default:
          throw new Error(`不支持的游戏类型: ${gameType}`);
      }
    } catch (error) {
      this.logger.error(
        `结算期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取需要结算的期数（分表逻辑）
   */
  async getRoundsToSettle(): Promise<UnifiedRoundData[]> {
    try {
      const [diceRounds, chibiRounds] = await Promise.all([
        this.diceRoundService.getRoundsToSettle(),
        this.chibiRoundService.getRoundsToSettle(),
      ]);

      const unifiedRounds: UnifiedRoundData[] = [];

      // 转换大小玩法期数
      diceRounds.forEach((round) => {
        unifiedRounds.push(this.convertRoundToUnified(round, GameType.DICE));
      });

      // 转换赤壁玩法期数
      chibiRounds.forEach((round) => {
        unifiedRounds.push(this.convertRoundToUnified(round, GameType.CHIBI));
      });

      return unifiedRounds;
    } catch (error) {
      this.logger.error(
        `获取需要结算的期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return [];
    }
  }

  /**
   * 获取过期期数（分表逻辑）
   */
  async getExpiredRounds(): Promise<UnifiedRoundData[]> {
    try {
      const [diceRounds, chibiRounds] = await Promise.all([
        this.diceRoundService.getExpiredActiveRounds(),
        this.chibiRoundService.getExpiredActiveRounds(),
      ]);

      const unifiedRounds: UnifiedRoundData[] = [];

      // 转换大小玩法期数
      diceRounds.forEach((round) => {
        unifiedRounds.push(this.convertRoundToUnified(round, GameType.DICE));
      });

      // 转换赤壁玩法期数
      chibiRounds.forEach((round) => {
        unifiedRounds.push(this.convertRoundToUnified(round, GameType.CHIBI));
      });

      return unifiedRounds;
    } catch (error) {
      this.logger.error(
        `获取过期期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return [];
    }
  }


  /**
   * 获取期数统计信息（分表逻辑）
   */
  async getRoundStats(gameType: GameType): Promise<any> {
    try {
      let stats: any = null;

      switch (gameType) {
        case GameType.DICE:
          // 使用实际存在的方法获取统计信息
          const diceRounds = await this.diceRoundService.getHistoryRounds(
            1,
            1000
          );
          const diceActiveRounds =
            await this.diceRoundService.getCurrentRound();
          stats = {
            totalRounds: diceRounds.total,
            activeRounds: diceActiveRounds ? 1 : 0,
            totalBets: 0,
            totalAmount: 0,
          };
          break;
        case GameType.CHIBI:
          // 使用实际存在的方法获取统计信息
          const chibiRounds = await this.chibiRoundService.getHistoryRounds(
            1,
            1000
          );
          const chibiActiveRounds =
            await this.chibiRoundService.getCurrentRound();
          stats = {
            totalRounds: chibiRounds.total,
            activeRounds: chibiActiveRounds ? 1 : 0,
            totalBets: 0,
            totalAmount: 0,
          };
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return {
            totalRounds: 0,
            activeRounds: 0,
            totalBets: 0,
            totalAmount: 0,
          };
      }

      return stats;
    } catch (error) {
      this.logger.error(
        `获取期数统计失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return {
        totalRounds: 0,
        activeRounds: 0,
        totalBets: 0,
        totalAmount: 0,
      };
    }
  }

  /**
   * 更新期数统计信息（分表逻辑）
   */
  async updateRoundStats(
    roundId: number,
    totalGold: number,
    totalSilver: number,
    gameType: GameType
  ): Promise<void> {
    try {
      switch (gameType) {
        case GameType.DICE:
          await this.diceRoundService.updateRoundStats(
            roundId,
            totalGold,
            totalSilver
          );
          break;
        case GameType.CHIBI:
          // 赤壁服务需要7个参数：三个国家的金币和银币
          const perCountryGold = Math.floor(totalGold / 3);
          const perCountrySilver = Math.floor(totalSilver / 3);
          await this.chibiRoundService.updateRoundStats(
            roundId,
            perCountryGold,
            perCountrySilver, // 魏国
            perCountryGold,
            perCountrySilver, // 蜀国
            perCountryGold,
            perCountrySilver // 吴国
          );
          break;
        default:
          throw new Error(`不支持的游戏类型: ${gameType}`);
      }
    } catch (error) {
      this.logger.error(
        `更新期数统计失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 清理过期数据（分表逻辑）
   */
  async cleanupExpiredData(daysToKeep: number = 30): Promise<number> {
    try {
      const [diceCount, chibiCount] = await Promise.all([
        this.diceRoundService.cleanupExpiredRounds(daysToKeep),
        this.chibiRoundService.cleanupExpiredRounds(daysToKeep),
      ]);

      return (diceCount || 0) + (chibiCount || 0);
    } catch (error) {
      this.logger.error(
        `清理过期数据失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return 0;
    }
  }

  // ==================== 兼容原有接口的方法 ====================

  /**
   * 兼容原有接口：获取期数下注统计
   */
  async getRoundBetStatistics(
    roundId: number,
    gameType: GameType
  ): Promise<any> {
    try {
      let round: any = null;

      switch (gameType) {
        case GameType.DICE:
          round = await this.diceRoundService.getRoundById(roundId);
          break;
        case GameType.CHIBI:
          round = await this.chibiRoundService.getRoundById(roundId);
          break;
        default:
          this.logger.warn(`不支持的游戏类型: ${gameType}`);
          return this.getEmptyBetStatistics();
      }

      if (!round) {
        return this.getEmptyBetStatistics();
      }

      // 根据游戏类型返回相应的下注统计
      if (gameType === GameType.DICE) {
        return await this.computeDiceBetStatisticsFromBets(round.id);
      } else if (gameType === GameType.CHIBI) {
        return this.getChibiBetStatistics(round);
      } else {
        return this.getEmptyBetStatistics();
      }
    } catch (error) {
      this.logger.error(
        `获取期数下注统计失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return this.getEmptyBetStatistics();
    }
  }

  /**
   * 兼容原有接口：获取期数信息
   */
  async getRoundInfo(
    roundId: number,
    gameType: GameType
  ): Promise<UnifiedRoundData | null> {
    return this.getRoundByNumber(gameType, roundId);
  }

  /**
   * 兼容原有接口：设置开奖结果
   */
  async setResult(
    gameType: GameType,
    roundId: number,
    resultData: any
  ): Promise<void> {
    try {
      switch (gameType) {
        case GameType.DICE:
          // 对于大小玩法，需要更新具体的开奖结果字段
          await this.diceRoundService.updateRoundStatus(roundId, 1);
          break;
        case GameType.CHIBI:
          // 对于赤壁玩法，需要更新具体的开奖结果字段
          await this.chibiRoundService.updateRoundStatus(roundId, 1);
          break;
        default:
          throw new Error(`不支持的游戏类型: ${gameType}`);
      }

      this.logger.log(`期数 ${roundId} 开奖结果设置成功`);
    } catch (error) {
      this.logger.error(
        `设置开奖结果失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 兼容原有接口：获取期数统计（别名）
   */
  async getRoundStatistics(gameType: GameType): Promise<any> {
    return this.getRoundStats(gameType);
  }

  /**
   * 兼容原有接口：清理过期期数（别名）
   */
  async cleanupExpiredRounds(): Promise<number> {
    return this.cleanupExpiredData(30);
  }

  /**
   * 兼容原有接口：获取过期活跃期数
   */
  async getExpiredActiveRounds(): Promise<UnifiedRoundData[]> {
    return this.getExpiredRounds();
  }

  /**
   * 兼容原有接口：更新期数状态
   */
  async updateRoundStatus(
    roundId: number,
    status: number,
    gameType: GameType
  ): Promise<void> {
    try {
      switch (status) {
        case 1: // 开奖中
          await this.closeRound(roundId, gameType);
          break;
        case 2: // 已结算
          await this.settleRound(roundId, gameType);
          break;
        default:
          throw new Error("不支持的状态值");
      }
    } catch (error) {
      this.logger.error(
        `更新期数状态失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  // 私有方法：转换期数数据为统一格式
  private convertRoundToUnified(
    round: any,
    gameType: GameType
  ): UnifiedRoundData {
    const result = {
      id: round.id,
      gameType: gameType,
      roundNumber: round.roundNumber || round.id, // 优先使用roundNumber，兼容使用ID
      startTime: round.startTime,
      endTime: round.endTime,
      status: round.status,
      resultData: this.getResultData(round, gameType),
      totalGold: round.totalGold || round.totalBetAmount || 0,
      totalSilver: round.totalSilver || 0,
      created_at: round.created_at,
      updated_at: round.updated_at,
    };

    // 添加兼容方法
    (result as any).getDiceResult = () => {
      if (gameType === GameType.DICE) {
        return this.getResultData(round, gameType);
      }
      return null;
    };
    (result as any).getChibiResult = () => {
      if (gameType === GameType.CHIBI) {
        return this.getResultData(round, gameType);
      }
      return null;
    };
    (result as any).getRPSResult = () => {
      if (gameType === GameType.ROCK_PAPER_SCISSORS) {
        return this.getResultData(round, gameType);
      }
      return null;
    };

    return result as UnifiedRoundData;
  }

  // 直接从下注表汇总大小玩法统计
  private async computeDiceBetStatisticsFromBets(
    roundId: number
  ): Promise<any> {
    // 聚合查询：按 betType、currencyType 汇总当期有效下注（下注中/已开奖都计入？这里采用下注中+已开奖）
    const qb = this.diceBetRepository
      .createQueryBuilder("bet")
      .select([
        "bet.betType as betType",
        "bet.currencyType as currencyType",
        "SUM(bet.betAmount) as totalAmount",
      ])
      .where("bet.roundId = :roundId", { roundId })
      .andWhere("bet.status IN (:...statuses)", {
        statuses: [BetStatus.BETTING, BetStatus.SETTLED],
      })
      .groupBy("bet.betType")
      .addGroupBy("bet.currencyType");

    const rows = await qb.getRawMany();

    // 初始化为0
    const stats = this.getEmptyBetStatistics();

    const setVal = (betType: number, currency: number, amount: number) => {
      if (betType === BetType.BIG) {
        if (currency === CurrencyType.GOLD) stats.sumdagold = amount;
        else stats.sumdasliver = amount;
      } else if (betType === BetType.SMALL) {
        if (currency === CurrencyType.GOLD) stats.sumxiaogold = amount;
        else stats.sumxiaosliver = amount;
      } else if (betType === BetType.ODD) {
        if (currency === CurrencyType.GOLD) stats.sumdangold = amount;
        else stats.sumdansliver = amount;
      } else if (betType === BetType.EVEN) {
        if (currency === CurrencyType.GOLD) stats.sumshuanggold = amount;
        else stats.sumshuangsliver = amount;
      } else if (betType === BetType.TRIPLE) {
        if (currency === CurrencyType.GOLD) stats.sumbaozigold = amount;
        else stats.sumbaozisliver = amount;
      }
    };

    for (const row of rows) {
      const betType = Number(row.betType);
      const currencyType = Number(row.currencyType);
      const totalAmount = Number(row.totalAmount) || 0;
      setVal(betType, currencyType, totalAmount);
    }

    return stats;
  }

  // 获取开奖结果数据
  private getResultData(round: any, gameType: GameType): any {
    if (gameType === GameType.DICE) {
      return round.getDiceResult ? round.getDiceResult() : null;
    } else if (gameType === GameType.CHIBI) {
      return round.getChibiResult ? round.getChibiResult() : null;
    } else if (gameType === GameType.ROCK_PAPER_SCISSORS) {
      return {
        winnerId: round.winnerId,
        winAmount: round.winAmount,
        isDraw: round.isDraw,
        totalChallenges: round.totalChallenges,
        totalResponded: round.totalResponded,
        totalSettled: round.totalSettled,
        totalBetAmount: round.totalBetAmount,
        totalWinAmount: round.totalWinAmount,
      };
    }
    return null;
  }

  // 获取空的下注统计
  private getEmptyBetStatistics(): any {
    return {
      sumdagold: 0,
      sumdasliver: 0,
      sumxiaogold: 0,
      sumxiaosliver: 0,
      sumdangold: 0,
      sumdansliver: 0,
      sumshuanggold: 0,
      sumshuangsliver: 0,
      sumbaozigold: 0,
      sumbaozisliver: 0,
    };
  }

  // 原函数已由下注表聚合替代

  // 获取赤壁玩法下注统计
  private getChibiBetStatistics(round: any): any {
    const totalGold = round.totalBetAmount
      ? Math.floor(round.totalBetAmount * 0.5)
      : 0;
    const totalSilver = round.totalBetAmount
      ? Math.floor(round.totalBetAmount * 0.5)
      : 0;

    return {
      sumdagold: Math.floor(totalGold * 0.33), // 魏国
      sumdasliver: Math.floor(totalSilver * 0.33),
      sumxiaogold: Math.floor(totalGold * 0.33), // 蜀国
      sumxiaosliver: Math.floor(totalSilver * 0.33),
      sumdangold: Math.floor(totalGold * 0.34), // 吴国
      sumdansliver: Math.floor(totalSilver * 0.34),
      sumshuanggold: 0,
      sumshuangsliver: 0,
      sumbaozigold: 0,
      sumbaozisliver: 0,
    };
  }
}
